import { MinusCircleOutlined, PlusOutlined, SyncOutlined } from '@ant-design/icons';
import { Button, Input, Select } from 'antd';
import { debounce } from 'lodash';
import React, { useMemo, useState } from 'react';
import { Position, useReactFlow } from 'reactflow';
import { useContextSelector } from 'use-context-selector';

import { DraggableProvided, DraggableStateSnapshot } from '@/components/common/DndDrag';
import DragIcon from '@/components/common/DndDrag/DragIcon';
import { SvgIcon } from '@/components/icon';
import { t } from '@/locales/i18n';
import { AppContext } from '@/pages/app/detail/context';
import { WorkflowIOValueTypeEnum } from '@/types/workflow/constant';
import { ReferenceValueProps } from '@/types/workflow/io';
import {
  allConditionList,
  arrayConditionList,
  booleanConditionList,
  numberConditionList,
  objectConditionList,
  stringConditionList,
  VariableConditionEnum,
} from '@/types/workflow/template/system/ifElse/constant';
import { IfElseListItemType } from '@/types/workflow/template/system/ifElse/type';
import { getElseIFLabel, getHandleId } from '@/types/workflow/utils';
import { getRefData } from '@/utils/workflow/utils';

import { WorkflowContext } from '../../../context';
import { SourceHandle } from '../render/Handle';
import { ReferSelector, useReference } from '../render/RenderInput/templates/Reference';

const ListItem = ({
  provided,
  snapshot,
  conditionIndex,
  conditionItem,
  ifElseList,
  onUpdateIfElseList,
  nodeId,
}: {
  provided: DraggableProvided;
  snapshot: DraggableStateSnapshot;
  conditionIndex: number;
  conditionItem: IfElseListItemType;
  ifElseList: IfElseListItemType[];
  onUpdateIfElseList: (value: IfElseListItemType[]) => void;
  nodeId: string;
}) => {
  const { getZoom } = useReactFlow();
  const onDelEdge = useContextSelector(WorkflowContext, (v) => v.onDelEdge);
  const handleId = getHandleId(nodeId, 'source', getElseIFLabel(conditionIndex));
  const [isHovered, setIsHovered] = useState(false);
  const [hoverIndex, setHoverIndex] = useState(-1);

  const Render = useMemo(() => {
    return (
      <div className="relative mb-2 flex origin-top-left items-center">
        <div className="nodrag mb-0">
          <div
            className={`flex w-[560px] flex-col items-center gap-2 rounded-xl ${
              isHovered ? 'bg-error/10' : 'bg-fill-2'
            } p-2 text-xs`}
          >
            <div className="flex w-full items-center">
              {ifElseList.length > 1 && (
                <DragIcon className="flex items-center" provided={provided} />
              )}
              <div className="ml-2 text-sm font-font-weight-600 text-text-5">
                {getElseIFLabel(conditionIndex)}
              </div>
              {ifElseList.length > 1 && (
                <Button
                  danger
                  className="ml-auto cursor-pointer hover:!bg-error/10 hover:!text-error"
                  type="text"
                  icon={<SvgIcon icon="delete-outlined" />}
                  onMouseEnter={() => setIsHovered(true)}
                  onMouseLeave={() => setIsHovered(false)}
                  onClick={() => {
                    onUpdateIfElseList(ifElseList.filter((_, index) => index !== conditionIndex));
                    onDelEdge({
                      nodeId,
                      sourceHandle: handleId,
                    });
                  }}
                />
              )}
            </div>

            <div className="flex w-full">
              {conditionItem.list?.length > 1 && (
                <div className="ml-6 mr-4">
                  <div className="border-divider-deep z-0 flex h-full w-6 items-center rounded-l-[8px] border border-r-0 border-text-2">
                    <div
                      className="z-10 -ml-6 flex cursor-pointer justify-center rounded-md border border-line-2 bg-fill-1 px-2 py-1 text-xs font-medium text-primary"
                      onClick={() => {
                        onUpdateIfElseList(
                          ifElseList.map((ifElse, index) => {
                            if (index === conditionIndex) {
                              return {
                                ...ifElse,
                                condition: ifElse.condition === 'AND' ? 'OR' : 'AND',
                              };
                            }
                            return ifElse;
                          }),
                        );
                      }}
                    >
                      <span className="mr-1">{conditionItem.condition}</span>
                      <SyncOutlined />
                    </div>
                  </div>
                </div>
              )}
              <div className="w-full">
                {conditionItem.list?.map((item, i) => {
                  return (
                    <div key={i} className="flex w-full">
                      {/* condition list */}

                      <div
                        className={`relative ${
                          i === conditionItem.list.length - 1 ? '' : 'mb-2'
                        } flex flex-1 flex-col justify-center gap-1 rounded-lg bg-fill-quaternary`}
                      >
                        <div className="flex items-center justify-center gap-1">
                          {/* variable reference */}
                          <div className="flex h-full flex-grow">
                            <Reference
                              nodeId={nodeId}
                              variable={item.variable}
                              onSelect={(e) => {
                                onUpdateIfElseList(
                                  ifElseList.map((ifElse, index) => {
                                    if (index === conditionIndex) {
                                      return {
                                        ...ifElse,
                                        list: ifElse.list.map((item, index) => {
                                          if (index === i) {
                                            return {
                                              ...item,
                                              variable: e,
                                              condition: undefined,
                                            };
                                          }
                                          return item;
                                        }),
                                      };
                                    }
                                    return ifElse;
                                  }),
                                );
                              }}
                            />
                          </div>
                          {/* condition select */}
                          <div className="ml-auto w-[160px]">
                            <ConditionSelect
                              condition={item.condition}
                              variable={item.variable}
                              onSelect={(e) => {
                                onUpdateIfElseList(
                                  ifElseList.map((ifElse, index) => {
                                    if (index === conditionIndex) {
                                      return {
                                        ...ifElse,
                                        list: ifElse.list.map((item, index) => {
                                          if (index === i) {
                                            return {
                                              ...item,
                                              condition: e,
                                            };
                                          }
                                          return item;
                                        }),
                                      };
                                    }
                                    return ifElse;
                                  }),
                                );
                              }}
                            />
                          </div>
                        </div>
                        {/* value */}
                        <div>
                          <ConditionValueInput
                            value={item.value}
                            condition={item.condition}
                            variable={item.variable}
                            onChange={(e) => {
                              onUpdateIfElseList(
                                ifElseList.map((ifElse, index) => {
                                  return {
                                    ...ifElse,
                                    list:
                                      index === conditionIndex
                                        ? ifElse.list.map((item, index) => {
                                            if (index === i) {
                                              return {
                                                ...item,
                                                value: e,
                                              };
                                            }
                                            return item;
                                          })
                                        : ifElse.list,
                                  };
                                }),
                              );
                            }}
                          />
                        </div>

                        <div
                          className={`pointer-events-none absolute left-0 top-0 h-full w-full ${
                            i === hoverIndex ? 'rounded-md bg-error/10' : ''
                          }`}
                        />
                      </div>

                      {/* delete */}
                      <div className="ml-auto flex h-auto items-center justify-center">
                        {conditionItem.list.length > 1 && (
                          <Button
                            type="link"
                            danger
                            className="cursor-pointer text-gray-400 hover:text-error"
                            icon={<MinusCircleOutlined />}
                            onMouseEnter={() => setHoverIndex(i)}
                            onMouseLeave={() => setHoverIndex(-1)}
                            onClick={() => {
                              setHoverIndex(-1);
                              onUpdateIfElseList(
                                ifElseList.map((ifElse, index) => {
                                  if (index === conditionIndex) {
                                    return {
                                      ...ifElse,
                                      list: ifElse.list.filter((_, index) => index !== i),
                                    };
                                  }
                                  return ifElse;
                                }),
                              );
                            }}
                          />
                        )}
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>

            <div className="flex items-center">
              <Button
                className="text-sm text-primary"
                icon={<PlusOutlined />}
                type="text"
                onClick={() => {
                  onUpdateIfElseList(
                    ifElseList.map((ifElse, index) => {
                      if (index === conditionIndex) {
                        return {
                          ...ifElse,
                          list: ifElse.list.concat({
                            variable: undefined,
                            condition: undefined,
                            value: undefined,
                          }),
                        };
                      }
                      return ifElse;
                    }),
                  );
                }}
              >
                {t('core.module.input.add')}
              </Button>
            </div>
          </div>
        </div>
        {/* <div
          className={`pointer-events-none absolute left-0 top-0 -mt-1 h-full w-full ${
            isHovered ? 'rounded-md bg-error/10' : ''
          }`}
        ></div> */}
        {!snapshot.isDragging && (
          <SourceHandle
            nodeId={nodeId}
            handleId={handleId}
            position={Position.Right}
            translate={[19, 0]}
          />
        )}
      </div>
    );
  }, [
    conditionIndex,
    conditionItem.condition,
    conditionItem.list,
    handleId,
    ifElseList,
    nodeId,
    onDelEdge,
    onUpdateIfElseList,
    provided,
    snapshot.isDragging,
    isHovered,
    hoverIndex,
  ]);

  return (
    <div
      ref={provided.innerRef}
      {...provided.draggableProps}
      style={{
        ...provided.draggableProps.style,
        opacity: snapshot.isDragging ? 0.8 : 1,
      }}
    >
      {Render}
    </div>
  );
};

export default React.memo(ListItem);

const Reference = ({
  nodeId,
  variable,
  onSelect,
}: {
  nodeId: string;
  variable?: ReferenceValueProps;
  onSelect: (e: ReferenceValueProps) => void;
}) => {
  const { referenceList, formatValue } = useReference({
    nodeId,
    valueType: WorkflowIOValueTypeEnum.any,
    value: variable,
  });

  return (
    <ReferSelector
      placeholder={t('select_reference_variable')}
      list={referenceList}
      value={formatValue}
      onSelect={onSelect}
    />
  );
};

/* Different data types have different options */
const ConditionSelect = ({
  condition,
  variable,
  onSelect,
}: {
  condition?: VariableConditionEnum;
  variable?: ReferenceValueProps;
  onSelect: (e: VariableConditionEnum) => void;
}) => {
  const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList);
  const appDetail = useContextSelector(AppContext, (v) => v.appDetail);

  // get condition type
  const { valueType, required } = useMemo(() => {
    return getRefData({
      variable,
      nodeList,
      chatConfig: appDetail.chatConfig,
    });
  }, [appDetail.chatConfig, nodeList, variable]);

  const conditionList = useMemo(() => {
    if (valueType === WorkflowIOValueTypeEnum.string) return stringConditionList;
    if (valueType === WorkflowIOValueTypeEnum.number) return numberConditionList;
    if (valueType === WorkflowIOValueTypeEnum.boolean) return booleanConditionList;
    if (
      valueType === WorkflowIOValueTypeEnum.chatHistory ||
      valueType === WorkflowIOValueTypeEnum.datasetQuote ||
      valueType === WorkflowIOValueTypeEnum.dynamic ||
      valueType === WorkflowIOValueTypeEnum.selectApp ||
      valueType === WorkflowIOValueTypeEnum.arrayBoolean ||
      valueType === WorkflowIOValueTypeEnum.arrayNumber ||
      valueType === WorkflowIOValueTypeEnum.arrayObject ||
      valueType === WorkflowIOValueTypeEnum.arrayString
    )
      return arrayConditionList;
    if (valueType === WorkflowIOValueTypeEnum.object) return objectConditionList;

    if (valueType === WorkflowIOValueTypeEnum.any) return allConditionList;

    return [];
  }, [valueType]);
  const filterQuiredConditionList = useMemo(() => {
    const list = (() => {
      if (required) {
        return conditionList.filter(
          (item) =>
            item.value !== VariableConditionEnum.isEmpty &&
            item.value !== VariableConditionEnum.isNotEmpty,
        );
      }
      return conditionList;
    })();
    return list.map((item) => ({
      ...item,
      label: t(item.label),
    }));
  }, [conditionList, required]);

  return (
    // <MySelect
    //   className="nowheel"
    //   w={'100%'}
    //   list={filterQuiredConditionList}
    //   value={condition}
    //   onchange={onSelect}
    //   placeholder={t('chose_condition')}
    // />
    <Select
      style={{ width: '100%' }}
      className="nowheel workflow-select"
      popupClassName="workflow-dropdown"
      options={filterQuiredConditionList}
      value={condition}
      onChange={onSelect}
      placeholder={t('chose_condition')}
    />
  );
};

const ConditionValueInput = ({
  value = '',
  variable,
  condition,
  onChange,
}: {
  value?: string;
  variable?: ReferenceValueProps;
  condition?: VariableConditionEnum;
  onChange: (e: string) => void;
}) => {
  const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList);
  const [localValue, setLocalValue] = React.useState(value);

  // 使用 useEffect 来处理外部 value 变化
  React.useEffect(() => {
    setLocalValue(value);
  }, [value]);

  // 使用 useMemo 缓存防抖函数
  const debouncedOnChange = useMemo(
    () =>
      debounce((val: string) => {
        onChange(val);
      }, 300),
    [onChange],
  );

  // 处理输入变化
  const handleInputChange = React.useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const newValue = e.target.value;
      setLocalValue(newValue);
      debouncedOnChange(newValue);
    },
    [debouncedOnChange],
  );

  // get value type
  const valueType = useMemo(() => {
    if (!variable) return;
    const node = nodeList.find((node) => node.nodeId === variable[0]);

    if (!node) return WorkflowIOValueTypeEnum.any;
    const output = node.outputs.find((item) => item.id === variable[1]);

    if (!output) return WorkflowIOValueTypeEnum.any;
    return output.valueType;
  }, [nodeList, variable]);

  const Render = useMemo(() => {
    if (valueType === WorkflowIOValueTypeEnum.boolean) {
      return (
        <Select
          className="workflow-select"
          popupClassName="workflow-dropdown"
          options={[
            { label: 'True', value: 'true' },
            { label: 'False', value: 'false' },
          ]}
          onChange={onChange}
          value={value}
          placeholder={t('ifelse.Select value')}
          disabled={
            condition === VariableConditionEnum.isEmpty ||
            condition === VariableConditionEnum.isNotEmpty
          }
        />
      );
    }
    return (
      <Input
        value={localValue}
        placeholder={(() => {
          if (condition === VariableConditionEnum.reg) {
            return '/^((+|00)86)?1[3-9]d{9}$/';
          }
          if (
            condition === VariableConditionEnum.isEmpty ||
            condition === VariableConditionEnum.isNotEmpty
          ) {
            return '是否为空判断不需要输入值';
          }
          return t('ifelse.Input value');
        })()}
        className="workflow-input"
        bordered={false}
        disabled={
          condition === VariableConditionEnum.isEmpty ||
          condition === VariableConditionEnum.isNotEmpty
        }
        onChange={handleInputChange}
      />
    );
  }, [valueType, localValue, condition, handleInputChange, onChange, value]);

  return Render;
};
